package com.xyzq.cgate.core.component.hystrix;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.exception.HystrixRuntimeException;
import com.netflix.hystrix.exception.HystrixTimeoutException;
import com.xyzq.cgate.common.constant.Constants;
import com.xyzq.cgate.common.enums.RequestTypeEnum;
import com.xyzq.cgate.common.exception.CgateException;
import com.xyzq.cgate.common.rule.custom.entity.MatchCondition;
import com.xyzq.cgate.core.plugin.IPluginChain;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @author chenchen
 * @date 2019/6/25 12:48
 */
@Deprecated
public class HttpCommand extends HystrixCommand<Void> {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpCommandWebclient.class);

    private static final OkHttpClient okHttpClient = new OkHttpClient();

    private final ServerWebExchange exchange;

    private final IPluginChain chain;

    private final MatchCondition condition;

    private final String url;

    private final long retry;

    public HttpCommand(final HystrixCommand.Setter setter,
                                final ServerWebExchange exchange,
                                final IPluginChain chain,
                                final MatchCondition condition,
                                final String url,
                                final long retry) {
        super(setter);
        this.exchange = exchange;
        this.chain = chain;
        this.condition = condition;
        this.url = url;
        this.retry = retry;
        okHttpClient.connectTimeoutMillis();
    }

    @Override
    protected Void run() {
        if(StringUtils.equalsIgnoreCase(RequestTypeEnum.GET.getRequestType(), condition.getQueryType())) {
            HttpHeaders headers = exchange.getRequest().getHeaders();
            Request request = new Request.Builder()
                    .headers(Headers.of(headers.toSingleValueMap()))
                    .url(url)
                    .build();
            Call call = okHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    throw new CgateException(e.getMessage());
                }
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
                        exchange.getResponse().setStatusCode(HttpStatus.OK);
                        exchange.getAttributes().put(Constants.WEBCLIENT_RESPONSE, response);
                    }
                }
            });

        } else if(StringUtils.equalsIgnoreCase(RequestTypeEnum.POST.getRequestType(), condition.getQueryType())) {


        }

        return null;
    }

    @Override
    protected Void getFallback() {
        final Throwable exception = getExecutionException();
        if (exception instanceof HystrixRuntimeException) {
            HystrixRuntimeException e = (HystrixRuntimeException)exception;
            if (e.getFailureType() == HystrixRuntimeException.FailureType.TIMEOUT) {
                exchange.getResponse().setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
            } else {
                exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else if (exception instanceof HystrixTimeoutException) {
            exchange.getResponse().setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
        } else {
            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return null;
    }
}
